package core;

import java.util.ArrayList;
import java.util.List;

import card.Card;
import card.CardFactory;
import card.LandCard;


/**
 *
 * @author Anton
 *
 *Handles all information about the actual game, being the map, all cards at all positions
 *, including the deck, all effects
 */

public class Core {
	private static Core me;
	/** seed used for calculating random outcome **/
	private static int seed;
	protected Tile map[][];
	private List<UpdateListener> listeners = new ArrayList<UpdateListener>();

	/**
	 * Contains every card in the current game, including those in graveyard, on gameboard, in deck and on hand.
	 * Never remove cards from this list.
	 */
	protected List<Card> ingameCards=new ArrayList<Card>();
	protected List<Player> players=new ArrayList<Player>();

	/**
	 * Determines whos players turn it is.
	 */
	private Player currentPlayer;

	/**
	 * The Player running this instance of the program.
	 */
	private Player thisPlayer;

	private int turn = 1;
	private int turnCounter = 0;

	public static Core getInstance(){
		if (me==null){
			me=new Core();
		}

		return me;
	}

	private Core(){
		init();
	}

	public void init(){
		generateMap();
	}

	/**
	 * generates all tiles in Core. 
	 * Places a random landCard on every tile.
	 * Should only be called once.
	 */
	private void generateMap(){
		map=new Tile[Constants.MAPSIZE][Constants.MAPSIZE];
		for(int x=0; x<Constants.MAPSIZE; x++){
			for(int y=0; y<Constants.MAPSIZE; y++){
				map[x][y]=new Tile();
				LandCard c = CardFactory.getRandomLandCard();
				ingameCards.add(c);
				map[x][y].setLandCard(c);
			}
		}
	}

	public Tile[][] getMap(){
		return map;
	}



	public Card getCard(int id){
		return ingameCards.get(id);
	}
	public int getIdOfCard(Card c){
		return ingameCards.indexOf(c);
	}
	public List<Card> getAllCards(){
		return ingameCards;
	}

	public void addIngameCards(List<Card> addedCards){
		for(Card c : addedCards)
			addIngameCard(c);
	}
	public void addIngameCard(Card c){
		if(!ingameCards.contains(c))
			ingameCards.add(c);
	}
	
	public void setPlayers(List<Player> p){
		players = p;		
	}


	/**
	 * Changes to the next players turn. Also uses the CardDrawer to draw cards as well as adding to the turnCounter.
	 */
	public void changeCurrentPlayer(Player p, int i){
		currentPlayer = p;
		turn += i;
	}

	public Player getCurrentPlayer(){
		return currentPlayer;
	}
	/**
	 * returns the player running this instance of the program.
	 * @return
	 */
	public Player getThisPlayer(){
		return thisPlayer;
	}

	public int getTurn(){
		return turn;
	}

	public int getTurnCounter(){
		return turnCounter;
	}

	public void addTurnCounter(){
		turnCounter++;
	}

	public void resetTurnCounter(){
		turnCounter = 1;
	}

	public int getIdOfThisPlayer(){
		return players.indexOf(thisPlayer);
	}
	public void setThisPlayer(Player p){
		thisPlayer=p;
	}
	public List<Player> getPlayers(){
		return players;
	}

	public static int getRandomSeed(){
		return seed;
	}
	public static void setRandomSeed(int s){
		seed=s;
	}
	/**
	 * Tells all registered coreListeners to update
	 */
	public void updateAll(){
		for(UpdateListener l : listeners){
			l.update();
		}
	}
	public void addUpdateListener(UpdateListener l){
		listeners.add(l);
	}
	/**
	 * checks if it's "this players" turn
	 * @return	
	 */
	public Boolean isYourTurn(){
		if(currentPlayer == thisPlayer)
			return true;
		else
			return false;
	}


}
